package cc.rengu.igas.channel.uprk.core.service.trans;

import cc.rengu.igas.channel.uprk.common.constant.UprkParamConstant;
import cc.rengu.igas.channel.uprk.common.constant.UprkServiceConstant;
import cc.rengu.igas.channel.uprk.common.constant.UprkTreeNodeConstant;
import cc.rengu.igas.channel.uprk.common.enums.RespCodeEnum;
import cc.rengu.igas.channel.uprk.core.model.ChnlBizResponse;
import cc.rengu.igas.channel.uprk.core.service.base.AuthService;
import cc.rengu.igas.channel.uprk.facade.request.BankCardShareGenTokenRequest;
import cc.rengu.igas.channel.uprk.facade.response.BankCardShareGenTokenResponse;
import cc.rengu.jradp.schedule.Schedule;
import cc.rengu.oltp.service.common.dao.KeyInfoMapper;
import cc.rengu.oltp.service.common.dao.SecPlanInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.KeyInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.SecPlanInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.*;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.RedisUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.communication.HttpMethod;
import com.alibaba.fastjson.JSONObject;

import java.util.List;
import java.util.Optional;


/**
 * @version 1.0.0
 * @date 2021/4/26 14:07
 */
public class BankCardShareGenTokenService extends AuthService {

    @Override
    protected Object beforeBizProcess() throws Exception {
        BankCardShareGenTokenRequest bankCardShareGenTokenRequest = new BankCardShareGenTokenRequest();
        ConvertUtil.convertOutput(bankCardShareGenTokenRequest);
        return bankCardShareGenTokenRequest;
    }

    @Override
    protected ChnlBizResponse callBizService(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        BankCardShareGenTokenRequest bankCardShareGenTokenRequest = (BankCardShareGenTokenRequest) request;
        BankCardShareGenTokenResponse bankCardShareGenTokenResponse = new BankCardShareGenTokenResponse();
        DstChannelCfg dstChannelCfg = (DstChannelCfg) xmlTreeUtil.getXmlTreeObjectValue(UprkTreeNodeConstant.DST_CHANNEL_CFG, DstChannelCfg.class);
        DstChannelInfo dstChannelInfo = (DstChannelInfo) xmlTreeUtil.getXmlTreeObjectValue(UprkTreeNodeConstant.DST_CHANNEL_INFO, DstChannelInfo.class);

        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam;
        String instId = bankCardShareGenTokenRequest.getHeader().getInstId();
        if (!StringUtil.isEmptyOrNull(bankCardShareGenTokenRequest.getAppid()) &&
                !StringUtil.isEmptyOrNull(bankCardShareGenTokenRequest.getAppSecret())) {
            xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.APP_ID, bankCardShareGenTokenRequest.getAppid());
            xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.APP_SECRET, bankCardShareGenTokenRequest.getAppSecret());
        } else {
            //字段上送为不全，则取数据库中配置的数据
           /* sysParam = sysParamService.getSysParamInfo(instId,"UNIONOPENPLATPARAM","app_id");
            if(null == sysParam){
                rglog.error("该行未配置银行卡风险信息共享查询参数app_id，请配置后进行处理!");
                throw new BizException(RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespCode(),RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespDesc());
            }*/
            xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.APP_ID, dstChannelCfg.getAppId());

           /* sysParam = sysParamService.getSysParamInfo(instId,"UNIONOPENPLATPARAM","app_secret");
            if(null == sysParam){
                rglog.error("该行未配置银行卡风险信息共享查询参数app_secret，请配置后进行处理!");
                throw new BizException(RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespCode(),RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespDesc());
            }*/
            String appSecret = getAppSecret(dstChannelCfg);
            if (null == appSecret) {
                rglog.error("该行未配置银行卡风险信息共享查询参数app_secret，请配置后进行处理!");
                throw new BizException(RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespCode(), RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespDesc());
            }
            xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.APP_SECRET, appSecret);
        }
        sysParam = sysParamService.getSysParamInfo(instId, "UPRKBANKCARDSHAREQUERY", "gettoken");
        if (null == sysParam) {
            rglog.error("该行未配置银行卡风险信息共享查询参数gettoken-requestUrl，请配置后进行处理!");
            throw new BizException(RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespCode(), RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespDesc());
        }
        String requestUrl = sysParam.getParamValue();
        requestUrl = requestUrl.replace("[app_id]", xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.APP_ID)).replace("[app_secret]", xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.APP_SECRET));
        xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.DEFINE_HTTP_URL_NODE, requestUrl);
        Schedule schedule = new Schedule();
        int iReturnCode = schedule.callService(UprkServiceConstant.UPRK_BANK_CARD_SHARE_CLIENT_SERVICE, HttpMethod.POST);
        if (xmlTreeUtil.isExist(UprkTreeNodeConstant.DEFINE_HTTP_URL_NODE)) {
            xmlTreeUtil.deleteXmlTreeNode(UprkTreeNodeConstant.DEFINE_HTTP_URL_NODE);
        }
        if (0 != iReturnCode) {
            //通讯失败
            throw new BizException(RespCodeEnum.REQUEST_UPRK_ERROR.getRespCode(), RespCodeEnum.REQUEST_UPRK_ERROR.getRespDesc());
        }
        //通讯成功
        String respCd = xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_CD);
        String token;
        String expireIn;
        if (UprkParamConstant.BANK_CARD_SHARE_SUCCESS.equals(respCd)) {
            //获取TOKEN成功
            token = xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.TOKEN);
            expireIn = xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.EXPIRE_IN);
            /*加载到redis缓存*/
            RedisUtil.onceSet(UprkParamConstant.UPRK_BANK_CARD_TOKEN_CACHE_NAME + xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.APP_ID), token, StringUtil.isEmptyOrNull(expireIn) ? UprkParamConstant.TOKEN_DEFAULT_EXPIRY_TIME : Integer.parseInt(expireIn));
        } else {
            //获取TOKEN失败
            rglog.error("获取银行卡风险信息查询产品TOKEN失败！");
            throw new BizException(StringUtil.isEmptyOrNull(xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_CD)) ? RespCodeEnum.GET_PROD_TOKEN_ERROR.getRespCode() : xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_CD),
                    StringUtil.isEmptyOrNull(xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_MSG)) ? RespCodeEnum.GET_PROD_TOKEN_ERROR.getRespDesc() : xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_MSG));
        }
        bankCardShareGenTokenResponse.setExpireIn(expireIn);
        bankCardShareGenTokenResponse.setToken(token);
        ChnlBizResponse chnlBizResponse = new ChnlBizResponse();
        chnlBizResponse.setResult(bankCardShareGenTokenResponse);
        rglog.debug("bankCardShareGenTokenResponse = <{}>", JSONObject.toJSONString(chnlBizResponse));
        return chnlBizResponse;
    }

    @Override
    protected void afterBizProcess(ChnlBizResponse response) throws Exception {
        BankCardShareGenTokenResponse bankCardShareGenTokenResponse = (BankCardShareGenTokenResponse) response.getResult();
        ConvertUtil.convertInput(bankCardShareGenTokenResponse);
    }

    private String getAppSecret(DstChannelCfg dstChannelCfg) throws Exception {
        /* 根据通道安全计划获取安全计划 */
        SecPlanInfoMapper secPlanInfoMapper = new SecPlanInfoMapperImpl();
        List<SecPlanInfo> secPlanInfoList = secPlanInfoMapper.selectSecPlanInfoBySecPlanId(dstChannelCfg.getInstId(), dstChannelCfg.getSecPlanId());
        if (null != secPlanInfoList && !secPlanInfoList.isEmpty()) {
            Optional<SecPlanInfo> secPlanInfoOpt = secPlanInfoList.stream().filter(item -> item.getSecPlanType().equals(UprkParamConstant.SECRET_KEY_TYPE)).findFirst();
            if (secPlanInfoOpt.isPresent()) {
                KeyInfoMapper keyInfoMapper = new KeyInfoMapperImpl();
                KeyInfo keyInfo = keyInfoMapper.selectKeyInfoByPrimaryKey(dstChannelCfg.getInstId() + secPlanInfoOpt.get().getSecPlanId() + secPlanInfoOpt.get().getSecPlanType());
                if (keyInfo != null) {
                    return keyInfo.getKeyValue();
                }
            }
        }
        return null;
    }
}
